/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
 * -*- coding: utf-8 -*-
 *
 * Copyright (C) 2022 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef PROXYSERVICEMANAGER_H
#define PROXYSERVICEMANAGER_H

#include <QObject>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusReply>
#include <QDir>
#include <unistd.h>
#include <glib.h>
#include <QtCore>
#include <QJsonArray>
#include <QJsonObject>
#include <QtDBus/QDBusMetaType>
#include <KWindowSystem>
#include <QDebug>

#define APPPROXY_FILE ".config/application-proxy.json"
#define PROXYCONF_FILE ".config/proto-config.json"
#define CUSTOMAPP_FILE "/usr/share/custom_app/custom_app.json"

#define JSON_KEY_APPLICATION "application"
#define DESKTOP_FILE_PATH       "/usr/share/applications/"
#define USR_SHARE_APP_CURRENT   "/usr/share/applications/."
#define USR_SHARE_APP_UPER      "/usr/share/applications/.."

#define GET_DESKTOP_EXEC_NAME_MAIN          "cat %s | awk '{if($1~\"Exec=\")if($2~\"\%\"){print $1} else print}' | cut -d '=' -f 2"
#define ANDROID_FILE_PATH       "/.local/share/applications/"
#define ANDROID_APP_CURRENT     "/.local/share/applications/."
#define ANDROID_APP_UPER        "/.local/share/applications/.."

#define PROTOJSON_KEY_TYPE "type"
#define PROTOJSON_KEY_SERVER "Server"
#define PROTOJSON_KEY_PORT "Port"
#define PROTOJSON_KEY_USRNAME "UserName"
#define PROTOJSON_KEY_PASSWORD "Password"
#define PROTOJSON_KEY_NAME "name"
#define PROTOJSON_KEY_STATE "state"

class ProxyServiceManager : public QObject
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface","org.ukui.SettingsDaemon.AppProxy")
public:
    explicit ProxyServiceManager(QObject *parent = nullptr);
    void ProxyServiceManagerNew();
    void start();
    void stop();

private:
    void initProxyState();
    QString searchFromEnviron(KWindowInfo info, QFileInfoList list);
    QString searchAndroidApp(KWindowInfo info);
    QString compareClassName(QFileInfoList list);
    QString getDesktopFileName(QString cmd);
    QString compareCmdExec(QFileInfoList list);
    QString compareCmdName(QFileInfoList list);
    QString compareDesktopClass(QFileInfoList list);
    QString containsName(QFileInfoList list);
    QString compareLastStrategy(QFileInfoList list);
    QString confirmDesktopFile(KWindowInfo info);
    QJsonObject dealJsonObj(const QStringList configList);
    QJsonObject readJsonFile(QString filePath);
    void wirteJsonFile(QString filePath, const QJsonObject obj);
    void addProcDbus(const qint32 pid);
    void startProxyDbus(const QJsonObject obj);
    void addProxyDbus(const QJsonObject obj);
    void clearProxyDbus();
    void startProxy(const QJsonObject obj);
    void stopProxyDbus();
    void stopProxy();
    void delValueFromArray(QJsonArray *array, const QJsonValue item);
    void setProxyFile(QString desktopfp, bool create);
    QMap<QString, QStringList> initAppInfoMap();

    QStringList getAppProxyFromFile();
    QStringList getDesktopFilePath();

    QString getAppName(QString desktopfp);
    QString getAppIcon(QString desktopfp);

    QStringList getCustomizedAppList(QString filePath);
    void recursiveSearchFile(const QString &_filePath);
    void getAndroidApp();

    void datacpy(void *dest,int dstLen, const void *src, int srcLen);
    QString getTerminalOutput(const QString & strCmd);
    QStringList getProcAllPid(const QString& ppid);
    bool getPidByName();

    inline bool getProxyState() {
        return m_proxyState;
    }
    inline void setProxyState(bool state) {
        m_proxyState = state;
    }

private:
    QDBusInterface  *m_proxyInterface = nullptr;

    QStringList m_filePathList;
    QStringList m_androidDesktopfnList;

    QString m_classClass = nullptr;
    QString m_className = nullptr;
    QString m_statusName = nullptr;
    QString m_cmdLine = nullptr;

    GError **m_error = nullptr;
    GKeyFileFlags m_flags = G_KEY_FILE_NONE;
    GKeyFile *m_keyfile = nullptr;

    bool m_proxyState = false;

    QTimer *m_time;

public Q_SLOTS:
    QStringList getProxyConfig();
    void setProxyConfig(const QStringList configList);
    QMap<QString, QStringList> getAppProxy();
    void addAppIntoProxy(QString desktopfp);
    void delAppIntoProxy(QString desktopfp);
    void setProxyStateDbus(bool state);
    bool getProxyStateDbus();

private Q_SLOTS:
    void init();
    void onWindowAdded(WId id);

Q_SIGNALS:

};

#endif // PROXYSERVICEMANAGER_H
